home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / spin3d.lzh / SPIN4.C < prev    next >
C/C++ Source or Header  |  1994-03-29  |  8KB  |  266 lines

  1. /*   *** SPIN4.C ***
  2.      ***************
  3.  
  4.  
  5.     Will spin ==========>  A triangle in 3 space <===============
  6.              
  7.     !!! New things:
  8.                  1) uses inline assembly routines to multiply 
  9.                     numbers...a little faster than previous versions
  10.                  2) modifies #1 and makes 2 assembly multiplication routines,
  11.                     one for COSINE multiplication and one for SINE mult.
  12.                     (This GREATLY speeds up multiplication, see benchmrk.txt
  13.                      for more details)
  14.  
  15.  
  16.     *** uses INTEGER ARITHMETIC for faster speed ***
  17.    
  18.     ** You can set up 3 diff projections  
  19.        project : xy, xz, or yz
  20.        just my slight modification of draw3dline()
  21.        for xz projection do
  22.           x1 = p1.x  y1 = p1.z
  23.           x2 = p2.x  y2 = p2.z     just DROP the y coord to project 
  24.                                    onto the XZ plane!
  25.  
  26.  
  27.    
  28.  
  29.  
  30.   
  31.  
  32.    March 28 ,1994  jeff bilger 
  33.    jbilger@cs.tamu.edu
  34.  
  35. */
  36.  
  37.  
  38. #include <math.h>
  39. #include <linea.h>
  40. #include <osbind.h>
  41. int pts[4][2] = { 
  42.     320, 050,
  43.     120, 150,
  44.     520, 150,
  45.     320, 050
  46. };
  47. lineaport *theport;
  48.  
  49. long mu_global_s();                     /* prototype, tells our 
  50.                                           Assembly language function
  51.                                            to return a long int  */
  52. long mu_global_c();  /* multiply 32 bit global w/ a precomputed sin or cos value */
  53.  
  54.  
  55. #define SCALE 2048L       /* so far 2048 is the upper bounds scale
  56.                               i can get W/O overflow */
  57. #define BITSH 11        /* what to shift (ie DIVIDE) by. this number
  58.                            2^11 = 2048 */
  59.  
  60.  
  61. typedef struct {long x,y,z;} point3d;   /* our faithful structure that defines a point in 3 space*/
  62.  
  63.           
  64. /* these are used to allocate size of arrays */
  65. #define NPTS   25                 /* max allowable points */
  66. #define NLINES 50                
  67. #define NFACES 50                
  68.  
  69.  
  70. #define I ( SCALE  )           /* set up a SCALE factor */
  71.  
  72. point3d point_[NPTS] =         /* define our triangle in 3d */
  73.         { 
  74.           I,I,I,     3*I,I,I, 2*I,I,-I,  2*I,-I,I/2,
  75.  },
  76.         drawpt1[NPTS],drawpt2[NPTS];     /* for fast draw/erasing look up */
  77.  
  78.  
  79.  
  80. int 
  81.     npts  = 4,         /* linefrom, lineto for drawing lines */                                                                                            
  82.     linefrom[NLINES] = {0,1,2,0,1,2},     /* set up lines to draw */
  83.     lineto[NLINES]   = {1,2,0,3,3,3}, 
  84.     nlines = 6,         /* number of lines */
  85.     x_offset=320,       /* for viewport mapping */
  86.     y_offset=100,
  87.     z_offset=1;
  88.  
  89. long cos_2=2048;    /* cos of 3 degrees * scale of 2048 */
  90. long sin_2=107;     /* sin of 3 degrees * scale of 2048 */
  91.  
  92.  
  93. main()
  94. {
  95. register int i,j;   /* use em for FOR loops */
  96. point3d pointi;     /* declare one instance of our point3d struct */
  97. int color =1;       /* color to draw triangle */
  98. char com;           /* for user input */
  99.  
  100.  
  101.  
  102.  
  103. puts("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  104. puts("1-Spin Y  2-Spin X  3-Spin Z  9-Quit\n");
  105.  
  106.  
  107. theport = a_init();                   /* line a invokage */    
  108.     theport -> plane0 = 1;
  109.     theport -> plane1 = 0;
  110.     theport -> plane2 = 0;
  111.     theport -> plane3 = 0;
  112.  
  113.  
  114.    
  115. for(i=0;i<nlines;i++)  /* set up points-to-connect lookup table*/
  116. { drawpt1[i] = point_[linefrom[i]];
  117.   drawpt2[i] = point_[lineto[i]];  
  118. }
  119.  
  120. com = 0x32;                       /* set to spin about x */
  121.  
  122. while( com != 0x39)
  123. {
  124. if( Bconstat(2) )       /* if keypress */
  125.  com = Bconin(2);       /* get input */
  126.  
  127.  
  128.                                   /* The main loop */
  129.  for(i=0;i<npts;i++)
  130.    {
  131.    pointi = point_[i];        /* get current point data. We do this for efficiency, since we will use this value many times within one loop
  132.                                  it's more efficient to compute it's value only once */
  133.    
  134.     if(com == 0x31) {              /* spin y */
  135.                point_[i].x =( mu_global_c(pointi.x)  -
  136.                               mu_global_s(pointi.z))>>BITSH; /* since our points are scaled AND or trig angles, sin&cos values are scaled we must divide by scale once here*/
  137.                point_[i].z =( mu_global_s(pointi.x) +
  138.                               mu_global_c(pointi.z))>>BITSH;
  139.  
  140.                     }
  141.     if(com == 0x32) {              /* spin x */
  142.                 point_[i].y =( mu_global_c(pointi.y)  +
  143.                                mu_global_s(pointi.z))>>BITSH;
  144.                 point_[i].z =( -(mu_global_s(pointi.y)) +
  145.                                  mu_global_c(pointi.z))>>BITSH;
  146.                     }
  147.     if(com == 0x33) {              /* spin z */
  148.                 point_[i].x =( mu_global_c(pointi.x)  +
  149.                                mu_global_s(pointi.y))>>BITSH;
  150.                 point_[i].y =( mu_global_c(pointi.y)  -
  151.                                mu_global_s(pointi.x))>>BITSH;
  152.                     }
  153.   
  154.  
  155.    }
  156.  
  157.                               /* draw and erase triangle */
  158.   for(i=0;i<nlines;i++)
  159.    { draw3dline(drawpt1[i],drawpt2[i],0);  /*erase */
  160.      draw3dline(drawpt1[i]=point_[linefrom[i]],drawpt2[i]=point_[lineto[i]],color);
  161.      /* draw it */
  162.   }
  163.    
  164.  
  165. }/* end of while */
  166.  
  167.  
  168.  
  169. } /* end of main */
  170.  
  171.  
  172.  
  173. /*******************************/
  174.  
  175. draw3dline(p1,p2,color)
  176. point3d p1,p2;
  177. int color;
  178. {
  179.  int x1,y1,x2,y2;
  180.  
  181.  /* project onto the xy plane */
  182.  x1 = (p1.x>>BITSH-5) + x_offset;      
  183.  y1 = (p1.y>>BITSH-5) + y_offset;
  184.  x2 = (p2.x>>BITSH-5) + x_offset;
  185.  y2 = (p2.y>>BITSH-5) + y_offset;
  186.  
  187. theport -> plane0 = color;
  188.  
  189. a_line(x1,y1,x2,y2); 
  190.  
  191. }
  192.  
  193.  
  194.  
  195. /***************************************************************/
  196. /* We will now modify the assembly mult. routine to be as efficient
  197.    as possible. We will make 2 mult. routines, one to multiply 
  198.    by a precomputed SINE value, and one to multiply by a precomputed
  199.    COSINE value
  200.    ************************************************************/
  201.  
  202. /*******************************************************/
  203. /* Multiply 1 16 bit(GLOBAL) SIGNED number b by a precomputed 
  204.    SINE value of 3 degrees (then the sine value was * SCALE where
  205.    scale was 2048 )
  206.  
  207.   and return the 32 bit result in D0
  208.  
  209.    *** BIG NOTE:: b MUST be a GLOBAL var!!!!!!!!!!!!!!!!!
  210.  
  211.    * WARNING * No test is made on the overflow bit (V) to see if 
  212.                the result in c is indeed correct. 
  213.  
  214.    Send arguments to this prodecure by: c=multiply(b) 
  215. */
  216.  
  217. long mu_global_s(b)
  218. register long b;  /* extern variables so b is placed in D7,*/          
  219. {
  220.  asm
  221.     { 
  222.   
  223.       muls   #107,b    /* generates  muls #107,d7 */
  224.       move.l b,D0  /* generates   move.l A7,(A5) */
  225.                     /* Note: You MUST specify the size (.l) cause
  226.                              if you just write 'move b,d0' Laser
  227.                              C will assume move.w as the default */
  228.      
  229.     }
  230.  
  231. }
  232.  
  233. /*************************************************
  234.  multiplies a number 'b' by a precomputed COSINE value
  235.  The Cos value is ===> cosine of 2 degrees * SCALE factor
  236.  where scale factor is defined. In our case the precomputed cos value 
  237.  is 2045 */
  238.  
  239. long mu_global_c(b)
  240. register long b;  /* extern variable so b is placed in D7*/
  241. {
  242.  asm
  243.     { 
  244.   
  245.       muls   #2045,b    /* generates  muls #2045,d7 */
  246.       move.l b,D0  /* generates   move.l A7,(A5) */
  247.                     /* Note: You MUST specify the size (.l) cause
  248.                              if you just write 'move b,d0' Laser
  249.                              C will assume move.w as the default */
  250.      
  251.     }
  252.  
  253. }
  254.  
  255.  
  256.  
  257. di(a,b)
  258. register long int a,b;
  259. {
  260.  asm
  261.     {
  262.      move.l a,D0
  263.      move.l b,D1
  264.     }
  265. }
  266.